package com.bac.rentmap.web.controller.ad.user.view;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class ViewStatisticsProxyController extends AbstractController {
    private static final Logger log = Logger.getLogger(ViewStatisticsProxyController.class
            .getName());
    private Pattern charsetPattern = Pattern.compile("charset=([\\w-]+)");
    private String slaveServerUrl;
    private String urlSuffix;

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String flatAdId = request.getParameter("flatAdId");
        String url = slaveServerUrl + urlSuffix + flatAdId;
        log.fine("Making GET request: url");
        InputStreamReader reader = getInputStreamReader(url);
        Writer writer = response.getWriter();
        int c;
        while((c = reader.read()) != -1){
            writer.write(c);
        }
        return null;
    }
    
    protected InputStreamReader getInputStreamReader(String url)
            throws IOException {
        url = trimUrl(url);
        log.info("Retrieving data from '" + url + "'");
        HttpURLConnection connection = createConnection(url);
        try {
            log.fine("Response headers: " + connection.getHeaderFields());
        } catch (RuntimeException e) {
            log.throwing(this.getClass().getCanonicalName(),
                    "getInputStreamReader", new IOException(
                            "Failed to crawl data from " + url, e));
        }
        if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new IOException("Invalid return code "
                    + connection.getResponseCode());
        }
        InputStream inputStream = connection.getInputStream();
        Charset charset = getCharset(connection);
        if (charset != null)
            return new InputStreamReader(inputStream, charset);
        else
            return new InputStreamReader(inputStream);
    }
    
    protected HttpURLConnection createConnection(String url)
            throws MalformedURLException, IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url)
                .openConnection();
        connection.setRequestProperty("Accept", "application/json");
        connection.setConnectTimeout(10000);
        return connection;
    }

    protected Charset getCharset(HttpURLConnection connection) {
        String contentTypeValue = connection.getHeaderField("content-type");
        if (contentTypeValue == null) {
            log.warning("Can't parse charset from content type header");
            return null;
        }
        String charset = parseCharset(contentTypeValue);
        if (charset == null) {
            log.warning("Can't parse charset from " + contentTypeValue);
            return null;
        }
        log.fine("Using charset: " + charset);
        return Charset.forName(charset);
    }
    
    public String parseCharset(String contentType) {
        Matcher matcher = charsetPattern.matcher(contentType);
        boolean matchFound = matcher.find();
        if (matchFound) {
            return matcher.group(1);
        }
        return null;
    }

    String trimUrl(String url){
        int i = url.indexOf('#');
        String res;
        if(i != -1){
            res = url.substring(0, i);
        }
        else{
            res = url;
        }
        return res;
    }


    @Required
    public void setSlaveServerUrl(String slaveServerUrl) {
        this.slaveServerUrl = slaveServerUrl;
    }

    @Required
    public void setUrlSuffix(String urlSuffix) {
        this.urlSuffix = urlSuffix;
    }    
}
